﻿using CoreDomain.BusinessCore;
using DomainService.IService.Sys;
using Infrastructure;
using Infrastructure.IRepository.Sys;
using Infrastructure.Repository.Sys;
using Model;
using Model.BusinessModel;
using Model.BusinessModel.OutPut;
using Model.BusinessModel.OutPut.sys;
using Model.DomainModel.Sys;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Data;
using System.Reflection.Emit;
using Utility;
using Utility.Enum;

namespace DomainService.Service.Sys
{

    /// <summary>
    /// 按钮服务实现
    /// </summary>
    /// <remarks>
    /// 构造函数 实现依赖注入
    /// </remarks>
    /// <param name="sysButtonRepository"></param>
    /// <param name="sysButtonRoleRepository"></param>
    /// <param name="sysCorporationRepository"></param>
    /// <param name="sysSystemRepository"></param>
    /// <param name="menuRepository"></param>
    /// <param name="sysUserRepository"></param>
    /// <param name="sysUserRoleRelationRepository"></param>
    public class SysButtonService(ISysButtonRepository sysButtonRepository, ISysButtonRoleRepository sysButtonRoleRepository, ISysCorporationRepository sysCorporationRepository, ISysSystemRepository sysSystemRepository, ISysMenuRepository menuRepository, ISysUserRepository sysUserRepository, ISysUserRoleRelationRepository sysUserRoleRelationRepository
            ) : ISysButtonService
    {
        #region 构造实例化

        //仓储接口
        private readonly ISysButtonRepository _sysButtonRepository = sysButtonRepository;
        private readonly ISysButtonRoleRepository _sysButtonRoleRepository = sysButtonRoleRepository;

        /// <summary>
        /// 菜单仓储接口
        /// </summary>
        private readonly ISysMenuRepository _menuRepository = menuRepository;

        /// <summary>
        /// 公司仓储接口
        /// </summary>
        private readonly ISysCorporationRepository _sysCorporationRepository = sysCorporationRepository;

        /// <summary>
        /// 系统仓储接口
        /// </summary>
        private readonly ISysSystemRepository _sysSystemRepository = sysSystemRepository;

        /// <summary>
        /// 用户底层仓储
        /// </summary>
        private readonly ISysUserRepository _sysUserRepository = sysUserRepository;

        /// <summary>
        /// 用户角色关系仓储
        /// </summary>
        private readonly ISysUserRoleRelationRepository _sysUserRoleRelationRepository = sysUserRoleRelationRepository;

        #endregion

        #region 服务实现

        /// <summary>
        /// 新增按钮数据
        /// </summary>
        /// <param name="sysButton"></param>
        public ReceiveStatus Insert(SysButton sysButton)
        {
            ReceiveStatus receiveStatus = new ReceiveStatus();
            var result = Validate(sysButton);
            if (!result.success)
                return result;
            sysButton.ButtonId = Guid.NewGuid().ToString();
            _sysButtonRepository.Insert(sysButton, BaseSqlRepository.sysButton_insertSql);
            return receiveStatus;
        }

        /// <summary>
        /// 修改按钮数据
        /// </summary>
        /// <param name="sysButton"></param>
        public ReceiveStatus Update(SysButton sysButton)
        {
            ReceiveStatus receiveStatus = new ReceiveStatus();
            var result = Validate(sysButton);
            if (!result.success)
                return result;
            _sysButtonRepository.Update(sysButton, BaseSqlRepository.sysButton_updateSql);
            return receiveStatus;
        }

        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="sysButton"></param>
        /// <returns></returns>
        public ReceiveStatus Validate(SysButton sysButton)
        {
            ReceiveStatus receiveStatus = new ReceiveStatus();
            /*
            新增/修改前验证
            1、相同菜单下不能有重复的按钮名称和事件key
            */
            var buttonList = _sysButtonRepository.GetButtonByMenuId(sysButton.MenuId ?? string.Empty);
            foreach (var item in buttonList)
            {
                if (sysButton.ButtonName == item.ButtonName && item.ButtonId.ToLower() != sysButton.ButtonId.ToLower())
                    return ExceptionHelper.CustomException(string.Format("该菜单已存在按钮名称为【{0}】的按钮,请重新输入", sysButton.ButtonName));
                if (sysButton.ButtonKey.ToLower() == item.ButtonKey.ToLower() && item.ButtonId.ToLower() != sysButton.ButtonId.ToLower())
                    return ExceptionHelper.CustomException(string.Format("该菜单已存在按钮事件为【{0}】的按钮,请重新输入", sysButton.ButtonKey));
            }

            return receiveStatus;
        }

        /// <summary>
        ///  获取按钮数据
        /// </summary>
        /// <param name="pageResultModel">分页模型</param>
        /// <returns>返回按钮数据</returns>
        public PageResultModel<SysButtonDataOutPut> GetButtonList(PageResultModel pageResultModel)
        {
            var selectWhere = string.Empty;
            JObject jobj = JObject.Parse(pageResultModel.filterJson ?? string.Empty);
            var menuId = jobj["MenuId"].ToString();
            var corporationKey = jobj["CorporationKey"].ToString();
            var systemKey = jobj["SystemKey"].ToString();
            var buttonId = jobj["ButtonId"].ToString();

            if (!string.IsNullOrWhiteSpace(menuId))
            {
                var menuModel = _menuRepository.GetByKey(menuId, BaseSqlRepository.sysMenu_selectByKeySql);
                var menuIdList = MenuCore.GetChildrenRoleById(menuId, menuModel.CorporationKey ?? string.Empty, menuModel.SystemKey ?? string.Empty);
                selectWhere = string.Format("and  Id in ('{0}')  ", string.Join("','", menuIdList.ToArray()));
            }
            if (!string.IsNullOrWhiteSpace(corporationKey))
                selectWhere = string.Format(" and m.CorporationKey = '{0}' ", corporationKey);
            if (!string.IsNullOrWhiteSpace(systemKey))
                selectWhere = string.Format(" and m.SystemKey = '{0}' ", systemKey);
            if (!string.IsNullOrWhiteSpace(buttonId))
                selectWhere = string.Format(" and b.ButtonId = '{0}' ", buttonId);

            pageResultModel.selectWhere = selectWhere;

            pageResultModel.tableField = " m.Name as MenuName,b.MenuId,m.CorporationKey,ss.SystemName,sc.CorporationName,ss.SystemKey,b.ButtonRoleType,b.ButtonStyleId,b.ButtonId,b.RuleId,b.ButtonName,b.ButtonKey,b.OrderBy,b.CreateUser,b.CreateTime,su.UserName,bs.ButtonStyleName,bs.Icon,bs.Color,bs.TextColor,bs.Types,bs.Size,bs.IsText,bs.IsRound,bs.IsCircle,bs.IsPlain,bs.IsLink,bs.IsDisabled";
            pageResultModel.tableName = @" Sys_Button as b  
                                            inner join Sys_Corporation as sc on sc.CorporationKey = b.CorporationKey
                                            inner join Sys_System as ss on b.SystemKey = ss.SystemKey
                                            inner join  Sys_ButtonStyle as bs  on b.ButtonStyleId = bs.ButtonStyleId
                                            inner join  Sys_Menu as m  on b.MenuId = m.Id
                                            inner  join Sys_User as su on su.UserId = b.CreateUser ";
            pageResultModel.orderByField = " b.CreateTime ";
            pageResultModel.sortType = " desc ";
            var list = _sysButtonRepository.GetPageList<SysButtonDataOutPut>(pageResultModel);

            return list;
        }

        /// <summary>
        /// 获取公司、系统、菜单、按钮关系数据
        /// </summary>
        /// <param name="corporationKey">公司key</param>
        /// <returns></returns>
        public ReceiveStatus<TreeExtendOutPut<SysButtonDataOutPut>> GetAllButtonList(string corporationKey)
        {
            ReceiveStatus<TreeExtendOutPut<SysButtonDataOutPut>> receiveStatus = new();

            //if (string.IsNullOrEmpty(corporationKey))
            //    return ExceptionHelper<TreeOutPut<SysButtonDataOutPut>>.CustomExceptionData("公司不能为空！");
            //if (string.IsNullOrEmpty(systemKey))
            //    return ExceptionHelper<TreeOutPut<SysButtonDataOutPut>>.CustomExceptionData("系统不能为空！");

            //公司信息
            var corporationModel = _sysCorporationRepository.GetByKey(corporationKey, BaseSqlRepository.sysCorporation_selectByKeySql);
            if (corporationModel == null)
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("公司不存在！");
            if (corporationModel.IsOpen == false)
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("公司已停用，不能设置！");

            //系统信息
            //var sysModel = _sysSystemRepository.GetByKey(systemKey, BaseSqlRepository.sysSystem_selectByKeySql);
            //if (sysModel == null)
            //    return ExceptionHelper<TreeOutPut<SysButtonDataOutPut>>.CustomExceptionData("系统不存在！");
            //if (sysModel.IsOpen == false)
            //    return ExceptionHelper<TreeOutPut<SysButtonDataOutPut>>.CustomExceptionData("系统已停用,不能设置！");

            List<TreeExtendOutPut<SysButtonDataOutPut>> list = new();

            //获取公司、系统、菜单
            var corporationSystemMenuList = _menuRepository.GetCorporationSystemMenuData(corporationKey, string.Empty);
            foreach (var item in corporationSystemMenuList)
            {
                TreeExtendOutPut<SysButtonDataOutPut> menuModel = new()
                {
                    key = item.key,
                    pKey = item.pKey,
                    label = item.label,
                    icon = item.icon,
                    nodeType = item.nodeType,
                    SystemKey = item.SystemKey,
                    CorporationKey = item.CorporationKey,
                };
                list.Add(menuModel);
            }

            //获取按钮数据
            var buttonList = _sysButtonRepository.GetCorporationSystemButtonList(corporationKey, string.Empty, 0);

            foreach (var item in buttonList)
            {
                TreeExtendOutPut<SysButtonDataOutPut> buttonModel = new()
                {
                    key = item.ButtonId,
                    pKey = item.MenuId,
                    label = item.ButtonName,
                    icon = item.Icon,
                    extendData = item,
                    nodeType = (int)NodeTypeEnum.Button,
                };
                list.Add(buttonModel);
            }

            //把菜单递归转换成树形结构
            var tree = list.ConvertTreeData();
            receiveStatus.data = tree;

            return receiveStatus;
        }

        /// <summary>
        /// 获取公司下系统菜单按钮
        /// </summary>
        /// <param name="corporationKey">公司key</param>
        /// <param name="systemKey">系统key</param>
        /// <returns></returns>
        public ReceiveStatus<TreeExtendOutPut<SysButtonDataOutPut>> GetSystemMenuButtonList(string corporationKey, string systemKey)
        {
            ReceiveStatus<TreeExtendOutPut<SysButtonDataOutPut>> receiveStatus = new();
            if (string.IsNullOrEmpty(corporationKey))
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("公司不能为空！");
            if (string.IsNullOrEmpty(systemKey))
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("系统不能为空！");

            //公司信息
            var corporationModel = _sysCorporationRepository.GetByKey(corporationKey, BaseSqlRepository.sysCorporation_selectByKeySql);
            if (corporationModel == null)
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("公司不存在！");
            if (corporationModel.IsOpen == false)
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("公司已停用，不能设置！");

            //系统信息
            var sysModel = _sysSystemRepository.GetByKey(systemKey, BaseSqlRepository.sysSystem_selectByKeySql);
            if (sysModel == null)
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("系统不存在！");
            if (sysModel.IsOpen == false)
                return ExceptionHelper<TreeExtendOutPut<SysButtonDataOutPut>>.CustomExceptionData("系统已停用,不能设置！");

            //获取系统菜单数据
            List<TreeExtendOutPut<SysButtonDataOutPut>> list = new();
            var corporationSystemMenuList = _menuRepository.GetCorporationSystemMenuList(corporationKey, systemKey);
            foreach (var item in corporationSystemMenuList)
            {
                item.disabled = Const.OverallAuth_MenuKey.Any(f => f == item.key) ? true : false;
            }
            foreach (var item in corporationSystemMenuList)
            {
                TreeExtendOutPut<SysButtonDataOutPut> menuModel = new()
                {
                    key = item.key,
                    pKey = item.pKey,
                    label = item.label,
                    icon = item.icon,
                    nodeType = item.nodeType,
                    SystemKey = item.SystemKey,
                    CorporationKey = item.CorporationKey,
                    disabled = Const.OverallAuth_MenuKey.Any(f => f == item.key) ? true : false
                };
                list.Add(menuModel);
            }
            //获取按钮数据
            var buttonList = _sysButtonRepository.GetCorporationSystemButtonList(corporationKey, systemKey, (int)ButtonRoleTypeEnum.MenuButton);

            foreach (var item in buttonList)
            {
                TreeExtendOutPut<SysButtonDataOutPut> buttonModel = new()
                {
                    key = item.ButtonId,
                    pKey = item.MenuId,
                    label = item.ButtonName,
                    icon = item.Icon,
                    extendData = item,
                    nodeType = (int)NodeTypeEnum.Button,
                };
                list.Add(buttonModel);
            }

            //把菜单递归转换成树形结构
            var tree = list.ConvertTreeData();
            receiveStatus.data = tree;
            return receiveStatus;
        }

        /// <summary>
        /// 获取菜单按钮
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <param name="corporationKey">公司key</param>
        /// <param name="systemKey">系统key</param>
        /// <param name="menuId">菜单key</param>
        /// <param name="buttonRoleType">按钮类型</param>
        /// <returns></returns>
        public ReceiveStatus<SysButtonDataOutPut> GetMenuButtonAuthList(string userId, string corporationKey, string systemKey, string menuId, int buttonRoleType)
        {
            ReceiveStatus<SysButtonDataOutPut> receiveStatus = new();
            //用户验证
            var userModel = _sysUserRepository.GetByKey(userId, BaseSqlRepository.sysUser_selectByKeySql);
            if (userModel == null)
                return ExceptionHelper<SysButtonDataOutPut>.CustomExceptionData("用户不存在");
            if (userModel.IsOpen == false)
                return ExceptionHelper<SysButtonDataOutPut>.CustomExceptionData(string.Format("用户【{0}】未启用", userModel.UserName));


            //不是登录星晨公司key的账号，默认赋值一个权限
            var userRoleList = new List<SysUserRoleRelationOutPut>();
            if (corporationKey != Const.XC_CorporationKey)
                userRoleList.Add(new SysUserRoleRelationOutPut { RoleId = Const.XC_DefaultRole });
            else
            {
                //获取用户角色,包括下级角色
                userRoleList = _sysUserRoleRelationRepository.GetSysUserRoleRelationsByUserId(userId, corporationKey, systemKey).Where(f => f.IsOpen).ToList();
                if (userRoleList.Count == 0)
                    return ExceptionHelper<SysButtonDataOutPut>.CustomExceptionData(string.Format("用户【{0}】未分配角色", userModel.UserName));
            }

            List<int> roleIdList = [];
            foreach (var item in userRoleList)
            {
                var roleIds = RoleCore.GetChildrenRoleById(item.RoleId, corporationKey, systemKey);
                roleIdList.AddRange(roleIds);
                roleIdList.Add(item.RoleId);
            }

            //获取角色拥有的所有按钮
            var allRoleHaveButtonList = _sysButtonRoleRepository.GetButtonByRoleIdOrMenuId(roleIdList, menuId);
            //获取菜单所有按钮
            var allMenuHaveButtonList = _sysButtonRepository.GetButtonStyleByMenuId(menuId).OrderBy(f => f.OrderBy).ToList();

            //把没有赋权限的按钮置灰
            foreach (var item in allMenuHaveButtonList)
            {
                if (!allRoleHaveButtonList.Any(f => f.ButtonId == item.ButtonId))
                    item.IsDisabled = true;
            }

            receiveStatus.data = allMenuHaveButtonList.Where(f => f.ButtonRoleType == buttonRoleType).ToList();
            receiveStatus.msg = "获取成功";
            return receiveStatus;
        }

        /// <summary>
        /// 获取菜单按钮
        /// </summary>
        /// <param name="menuId">菜单key</param>
        /// <param name="buttonRoleType">按钮类型</param>
        /// <returns></returns>
        public ReceiveStatus<SysButtonDataOutPut> GetMenuButtonList(string menuId, int buttonRoleType)
        {
            //获取数据
            ReceiveStatus<SysButtonDataOutPut> receiveStatus = new();
            var buttonList = new List<SysButtonDataOutPut>();
            buttonList = _sysButtonRepository.GetButtonStyleByMenuId(menuId);

            //获取按钮数据
            if (buttonRoleType != 0)
            {
                buttonList = buttonList.Where(f => f.ButtonRoleType == buttonRoleType).ToList();
            }

            receiveStatus.data = buttonList;
            return receiveStatus;

        }
        #endregion
    }
}
